package com.nhn.productmyself.lib.common;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Point;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

public class CommonUtils {

	public enum DensityType {
		XXXHDPI, XXHDPI, XHDPI, HDPI, MDPI, LDPI
	}

	/**
	 * Check the current activity is last activity or not.
	 * 
	 * @param context
	 *            the context
	 * @return true, if is last activity
	 */
	public static boolean isLastActivity(Context context) {
		final ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		final List<RunningTaskInfo> tasksInfo = am.getRunningTasks(1024);

		final String ourAppPackageName = context.getPackageName();
		RunningTaskInfo taskInfo;
		final int size = tasksInfo.size();
		for (int i = 0; i < size; i++) {
			taskInfo = tasksInfo.get(i);
			if (ourAppPackageName.equals(taskInfo.baseActivity.getPackageName())) {
				return taskInfo.numActivities == 1;
			}
		}
		return false;
	}

	/**
	 * Read file as string.
	 * 
	 * @param fileName
	 *            the file name
	 * @return the string
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static String readFileAsString(String fileName) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(fileName));
		try {
			StringBuilder sb = new StringBuilder();
			String line = br.readLine();

			while (line != null) {
				sb.append(line);
				sb.append("\n");
				line = br.readLine();
			}
			return sb.toString();
		} finally {
			br.close();
		}
	}

	/**
	 * Read file as string.
	 * 
	 * @param inputStream
	 *            the input stream
	 * @return the string
	 */
	public static String readFileAsString(InputStream inputStream) {
		BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
		try {
			StringBuilder sb = new StringBuilder();
			String line = br.readLine();

			while (line != null) {
				sb.append(line);
				sb.append("\n");
				line = br.readLine();
			}
			return sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Gets the demension device.
	 * 
	 * @param context
	 *            the context
	 * @return the demension device
	 */
	public static Point getDimensionDevice(Context context) {
		WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		Display display = manager.getDefaultDisplay();
		Point size = new Point();
		DisplayMetrics dm = new DisplayMetrics();
		display.getMetrics(dm);
		display.getSize(size);
		return size;
	}

	/**
	 * Gets the screen orientation.
	 * 
	 * @param context
	 *            the context
	 * @return the screen orientation
	 */
	public static int getScreenOrientation(Context context) {
		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		Display getOrient = windowManager.getDefaultDisplay();
		int orientation = Configuration.ORIENTATION_UNDEFINED;
		if (getOrient.getWidth() == getOrient.getHeight()) {
			orientation = Configuration.ORIENTATION_SQUARE;
		} else {
			if (getOrient.getWidth() < getOrient.getHeight()) {
				orientation = Configuration.ORIENTATION_PORTRAIT;
			} else {
				orientation = Configuration.ORIENTATION_LANDSCAPE;
			}
		}
		return orientation;
	}

	/**
	 * Gets the density type.
	 * 
	 * @param context
	 *            the context
	 * @return the density type
	 */
	public static DensityType getDensityType(Context context) {
		float density = context.getResources().getDisplayMetrics().density;
		if (density >= 4.0) {
			return DensityType.XXXHDPI;
		}
		if (density >= 3.0) {
			return DensityType.XXHDPI;
		}
		if (density >= 2.0) {
			return DensityType.XHDPI;
		}
		if (density >= 1.5) {
			return DensityType.HDPI;
		}
		if (density >= 1.0) {
			return DensityType.MDPI;
		}
		return DensityType.LDPI;
	}

	/**
	 * This method converts dp unit to equivalent pixels, depending on device
	 * density.
	 * 
	 * @param dp
	 *            A value in dp (density independent pixels) unit. Which we need
	 *            to convert into pixels
	 * @param context
	 *            Context to get resources and device specific display metrics
	 * @return A float value to represent px equivalent to dp depending on
	 *         device density
	 */
	public static float convertDpToPixel(float dp, Context context) {
		Resources resources = context.getResources();
		DisplayMetrics metrics = resources.getDisplayMetrics();
		float px = dp * (metrics.densityDpi / 160f);
		return px;
	}

	/**
	 * This method converts device specific pixels to density independent
	 * pixels.
	 * 
	 * @param px
	 *            A value in px (pixels) unit. Which we need to convert into db
	 * @param context
	 *            Context to get resources and device specific display metrics
	 * @return A float value to represent dp equivalent to px value
	 */
	public static float convertPixelsToDp(float px, Context context) {
		Resources resources = context.getResources();
		DisplayMetrics metrics = resources.getDisplayMetrics();
		float dp = px / (metrics.densityDpi / 160f);
		return dp;
	}

	/**
	 * Convert pixels to SP.
	 * 
	 * @param context
	 *            the context
	 * @param px
	 *            the number of pixel
	 * @return the float
	 */
	public static float convertPixelsToSp(Context context, float px) {
		float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
		return px / scaledDensity;
	}

	/**
	 * Convert sp to pixels.
	 * 
	 * @param context
	 *            the context
	 * @param sp
	 *            the sp
	 * @return the float
	 */
	public static float convertSpToPixels(Context context, float sp) {
		Resources resources = context.getResources();
		DisplayMetrics metrics = resources.getDisplayMetrics();
		float pixelSize = (int) sp * metrics.scaledDensity;
		return pixelSize;
	}

	/**
	 * Checks if the device is a tablet or a phone
	 * 
	 * @param context
	 *            The Activity Context.
	 * @return Returns true if the device is a Tablet
	 */
	public static boolean isTabletDevice(Context context) {
		boolean device_large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE);

		if (device_large) {
			DisplayMetrics metrics = new DisplayMetrics();
			WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
			windowManager.getDefaultDisplay().getMetrics(metrics);

			if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
					|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
					|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
					|| metrics.densityDpi == DisplayMetrics.DENSITY_TV
					|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks if is package existed.
	 * 
	 * @param targetPackage
	 *            the target package
	 * @return true, if is package existed
	 */
	public static boolean isPackageExisted(Context context, String targetPackage) {
		List<ApplicationInfo> packages;
		PackageManager pm;
		pm = context.getPackageManager();
		packages = pm.getInstalledApplications(0);
		for (ApplicationInfo packageInfo : packages) {
			if (packageInfo.packageName.equals(targetPackage))
				return true;
		}
		return false;
	}

	/**
	 * Array to list.
	 * 
	 * @param <T>
	 *            the generic type
	 * @param array
	 *            the array
	 * @return the list
	 */
	public static <T> List<T> arrayToList(final T[] array) {
		final List<T> l = new ArrayList<T>(array.length);

		for (final T s : array) {
			l.add(s);
		}
		return (l);
	}

	/**
	 * Checks if is package installed.
	 *
	 * @param context the context
	 * @param packageName the package name
	 * @return true, if is package installed
	 */
	public static boolean isPackageInstalled(Context context, String packageName) {
		Intent intent = new Intent(packageName);
		List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
		return list.size() > 0;
	}
}
